package com.tentative.competition.schedule.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tentative.competition.common.core.result.PageResult;
import com.tentative.competition.common.enums.ScheduleStatusEnum;
import com.tentative.competition.common.model.schedule.param.ScheduleAdminPageParam;
import com.tentative.competition.common.model.schedule.param.ScheduleAdminParam;
import com.tentative.competition.common.model.schedule.resp.*;
import com.tentative.competition.common.model.schedule.vo.FileVo;
import com.tentative.competition.common.utils.BeanUtils;
import com.tentative.competition.common.utils.DateUtils;
import com.tentative.competition.schedule.domain.ScheduleAdmin;
import com.tentative.competition.schedule.mapper.ScheduleAdminMapper;
import com.tentative.competition.schedule.service.ScheduleAdminService;
import com.tentative.competition.schedule.service.ScheduleFileInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 赛程（大赛）管理 服务实现类
 * </p>
 *
 * @author SmileH
 * @since 2023-06-22
 */
@Service
public class ScheduleAdminServiceImpl extends ServiceImpl<ScheduleAdminMapper, ScheduleAdmin> implements IService<ScheduleAdmin>, ScheduleAdminService {

    @Lazy
    @Autowired
    private ScheduleFileInfoService fileInfoService;

    @Override
    public PageResult<ScheduleAdminResp> pageList(ScheduleAdminPageParam param) {
        IPage<ScheduleAdmin> iPage = this.lambdaQuery().eq(ScheduleAdmin::getDelFlag,0)
                .eq(StrUtil.isNotBlank(param.getName()),ScheduleAdmin::getScheduleTitle,param.getName())
                .page(new Page<>(param.getPageNum(),param.getPageSize()));
//        IPage<ScheduleAdminResp> iPage =  baseMapper.pageList(param,new Page<>(param.getPageNum(),param.getPageSize()));
        if(CollUtil.isEmpty(iPage.getRecords())){
            return new PageResult<ScheduleAdminResp>();
        }
        List<ScheduleAdminResp> list = BeanUtils.copyList(iPage.getRecords(),ScheduleAdminResp.class);
        PageResult<ScheduleAdminResp> pageResult = new PageResult<>();
        pageResult.setContent(list);
        pageResult.setTotal(iPage.getTotal());
        return pageResult;
    }

    @Override
    public void addOrEdit(ScheduleAdminParam param) {
        ScheduleAdmin admin = new ScheduleAdmin();
        BeanUtil.copyProperties(param,admin);
        if(admin.getScheduleEnd().getTime() <= System.currentTimeMillis()){
            admin.setScheduleStatus(ScheduleStatusEnum.ACCOMPLISH);
        }else{
            admin.setScheduleStatus(ScheduleStatusEnum.UNDERWAY);
        }
        if(param.getId() == null){
            //新建的赛程均为未开启状态
            admin.setScheduleStatus(ScheduleStatusEnum.US_START);
        }
        this.saveOrUpdate(admin);
    }

    @Override
    public ScheduleAdminResp getInfo(Long id) {
        ScheduleAdmin admin = this.lambdaQuery()
                .eq(ScheduleAdmin::getId,id)
                .eq(ScheduleAdmin::getDelFlag,0)
                .list()
                .stream()
                .findFirst()
                .orElse(null);
        if (ObjUtil.isEmpty(admin)){
            throw new RuntimeException("无法找到对象！");
        }
        ScheduleAdminResp resp = new ScheduleAdminResp();
        BeanUtil.copyProperties(admin,resp);
        Set<Long> fileIds = CollUtil.newHashSet();
        if (ObjUtil.isNotEmpty(resp.getScheduleLogo())){
            fileIds.add(resp.getScheduleLogo());
        }
        if (ObjUtil.isNotEmpty(resp.getScheduleLetter())){
            fileIds.add(resp.getScheduleLetter());
        }
        //开始组装附件信息
        Map<Long, FileVo> fileVoMap = fileInfoService.selectFileMapByIds(fileIds);
        if (ObjUtil.isNotEmpty(resp.getScheduleLogo())){
            resp.setScheduleLogoVo(fileVoMap.get(resp.getScheduleLogo()));
        }
        if (ObjUtil.isNotEmpty(resp.getScheduleLetter())){
            resp.setScheduleLetterVo(fileVoMap.get(resp.getScheduleLetter()));
        }
        return resp;
    }

    @Override
    public ScheduleAdmin getNow() {
        return this.getNowScheduleAdmin();
    }

    @Override
    public Boolean deleteSchedule(List<Long> ids) {
        if (CollUtil.isEmpty(ids)){
            throw new RuntimeException("没有需要删除的数据！");
        }
        return this.lambdaUpdate()
                .in(ScheduleAdmin::getId,ids)
                .set(ScheduleAdmin::getDelFlag,1)
                .update();
    }

    @Override
    public ScheduleAdmin getNowScheduleAdmin(){
        ScheduleAdmin scheduleAdmin = this.lambdaQuery()
                .eq(ScheduleAdmin::getScheduleStatus, ScheduleStatusEnum.UNDERWAY)
                .eq(ScheduleAdmin::getDelFlag,0)
                .list()
                .stream()
                .findFirst().orElse(null);
        //如果不存在进行中的数据，此时网页也可以正常浏览，展示最近的赛程数据，避免太多地方用到赛程ID，而没有赛程ID导致报错从而影响体验
        if (ObjUtil.isEmpty(scheduleAdmin)){
            List<ScheduleAdmin> scheduleAdminList = this.lambdaQuery()
                    .eq(ScheduleAdmin::getDelFlag,0)
                    .orderByDesc(ScheduleAdmin::getCreateTime)
                    .list();
            if (CollUtil.isNotEmpty(scheduleAdminList)){
                scheduleAdmin = scheduleAdminList.get(0);
            }
        }
        return scheduleAdmin;
    }

    @Override
    public ScheduleInfoResp getBasicsInfo() {
        Long schedule = this.getNowScheduleAdmin().getId();
        ScheduleAdminResp adminResp = getInfo(schedule);
        ScheduleInfoResp resp = new ScheduleInfoResp();
        resp.setScheduleId(adminResp.getId());
        resp.setScheduleTitle(adminResp.getScheduleTitle());
        if (ObjUtil.isNotEmpty(adminResp.getScheduleLogoVo())){
            resp.setScheduleLogoUrl(adminResp.getScheduleLogoVo().getFileUrl());
        }
        if (ObjUtil.isNotEmpty(adminResp.getScheduleLetterVo())){
            resp.setLetterUrl(adminResp.getScheduleLetterVo().getFileUrl());
        }
        //时间判断
        int compareTo = DateUtils.compareTo(new Date(), adminResp.getPresentationTime());
        if (compareTo<0){
            resp.setFlag(false);
        }else {
            resp.setFlag(true);
        }

        return resp;
    }

    @Override
    public HomeIntroInfoResp getIntroInfo(Long id) {
        ScheduleAdminResp adminResp = getInfo(id);
        HomeIntroInfoResp resp = new HomeIntroInfoResp();
        resp.setIntroInfo(adminResp.getScheduleIntro());
        return resp;
    }

    @Override
    public List<GeneralMainResp> getSchedulePullDown(Long scheduleId) {
        List<ScheduleAdmin> scheduleAdmins = this.lambdaQuery()
                .ne(ScheduleAdmin::getId, scheduleId)
                .eq(ScheduleAdmin::getDelFlag,0)
                .list();
        if (CollUtil.isEmpty(scheduleAdmins)){
            return CollUtil.newArrayList();
        }
        return scheduleAdmins.stream().map(x->{
            GeneralMainResp resp = new GeneralMainResp();
            resp.setKey(x.getId().toString());
            resp.setVal(x.getScheduleLabel());
            return resp;
        }).collect(Collectors.toList());
    }

    @Override
    public void alterStateTask() {
        List<ScheduleAdmin> scheduleAdmins = this.lambdaQuery()
                .eq(ScheduleAdmin::getScheduleStatus, ScheduleStatusEnum.UNDERWAY)
                .eq(ScheduleAdmin::getDelFlag, 0)
                .list();
        if (CollUtil.isEmpty(scheduleAdmins)){
            return;
        }
        //过滤截止时间小于或者等于当前时间的赛程数据，修改为已完成
        List<ScheduleAdmin> list = CollUtil.newArrayList();
        scheduleAdmins.forEach(x->{
            if (ObjUtil.isNotEmpty(x.getScheduleEnd())){
                int compareTo = DateUtils.compareTo(new Date(), x.getScheduleEnd());
                if (compareTo >= BigDecimal.ROUND_UP){
                    list.add(x);
                }
            }
        });
        if (CollUtil.isNotEmpty(list)){
            list.forEach(x->x.setScheduleStatus(ScheduleStatusEnum.ACCOMPLISH));
            updateBatchById(list);
        }
    }

    @Override
    public Boolean editEnable(String scheduleStatus, Long scheduleId) {
        //如果修改为进行中，需要判断是否有赛程在进行中，如果有，则不能修改
        if (ScheduleStatusEnum.UNDERWAY.name().equals(scheduleStatus)){
            Long count = this.lambdaQuery()
                    .eq(ScheduleAdmin::getScheduleStatus, ScheduleStatusEnum.UNDERWAY)
                    .count();
            if (count > BigDecimal.ROUND_UP){
                throw new RuntimeException("已经有赛程正在火热进行中！");
            }
            return this.lambdaUpdate()
                    .eq(ScheduleAdmin::getId,scheduleId)
                    .set(ScheduleAdmin::getScheduleStatus,ScheduleStatusEnum.UNDERWAY)
                    .update();
        }
        if (ScheduleStatusEnum.ACCOMPLISH.name().equals(scheduleStatus)){
            return this.lambdaUpdate()
                    .eq(ScheduleAdmin::getId,scheduleId)
                    .set(ScheduleAdmin::getScheduleStatus,ScheduleStatusEnum.ACCOMPLISH)
                    .update();
        }
        return false;
    }

}
